﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

// Reviewed
#pragma once

#include "GcmpModelInterface.h"
#include "NdbDataSchema.h"
#include "NdbObjectSchematic.h"

namespace gcmp
{
    /// \brief UniIdentity类提供了跨文档的唯一标识符
    ///
    /// 目前提供Guid和调试用字符串
    /// 规划：将来会提供创建来源和修改历史
    class GCMP_MODEL_INTERFACE_EXPORT UniIdentity :public NdbObjectSchematic
    {
        DATA_BEGIN(gcmp, UniIdentity, gcmp::NdbObjectSchematic, 93A698B5 - 75CF - 4378 - 8C54 - 99783720C004, gcmpmodelinterface)
            DATA(Guid, Guid)
            DATA(std::wstring, DebugString)
        DATA_END
    public:
        UniIdentity(const Guid& guid);
        UniIdentity(const Guid& guid, const std::wstring& debugString);

    public:

        /// \brief 生成一个跨文档唯一的标识符
        ///       
        /// \return 跨文档唯一的标识符
        static UniIdentity Create();

        /// \brief 生成一个带辅助信息的跨文档唯一标识符，
        /// \param debugString          标识符辅助信息
        /// \return 跨文档唯一的标识符
        static UniIdentity Create(const std::wstring &debugString);

        /// \brief 根据给定Guid生成一个带辅助信息的跨文档唯一标识符
        /// 
        /// \param guid                 Guid
        /// \param debugString          标识符辅助信息
        /// \return 跨文档唯一的标识符
        static UniIdentity Create(const Guid& guid, const std::wstring& debugString);

        /// \brief 返回Guid格式的当前跨文档标识符
        ///
        /// \return Guid格式的跨文档标识符
        inline const Guid& GetGuid() const
        {
            return GetGuid__();
        }

        /// \brief 返回wstring格式的当前跨文档标识符
        ///       
        /// \return wstring格式的跨文档唯一标识符
        const std::wstring GetGuidString() const;

        /// \brief 返回当前跨文档标识符的辅助信息
        ///       
        /// \return 标识符的辅助信息
        const std::wstring& GetDebugString() const;

        /// \brief 返回wstring格式的标识符和辅助信息
        /// \return wstring格式的标识符和辅助信息
        const std::wstring GetGuidAndDebugString() const;

        /// \brief 判断当前标识符与给定的标识符是否相等
        /// 
        /// \param uniIdentity         标识符
        /// \return 两者相等返回true，否则返回false
        bool HasSameValue(const UniIdentity& uniIdentity)  const;

        /// \brief 返回当前跨文档标识符的有效性
        ///       
        /// \return 有效返回true，否则返回false
        bool IsValid() const;

    public: //实现NdbObject接口
        virtual NdbObject* GetTopOwnerObject() const override
        {
            return nullptr;
        }

    public:
        //无效的跨文档标识符
        static const UniIdentity InvalidUid;

    // 操作符重载，用于容器的创建
    public:
        bool operator < (const UniIdentity& other) const;
        //判断两个对象是否相等，内部判断Guid是否相等
        friend bool operator == (const UniIdentity& first, const UniIdentity& second) {return (first.GetGuid() == second.GetGuid()) == TRUE; }
        friend bool operator != (const UniIdentity& first, const UniIdentity& second) {return !(first == second); }
    };

    struct UniIdentityHash
    {
        std::size_t operator()(const UniIdentity& key) const
        {
            return std::hash<Int64>()(GuidHasher()(key.GetGuid()));
        }
    };
}





